Progetto DSIM - Retrieval


Autori: Ginevra Mariani | Lorenzo Mora | Confalonieri Riccardo
E-mail: g.mariani34@campus.unimib.it | l.mora4@campus.unimib.it | r.confalonieri5@campus.unimib.it

L'obiettivo di questo notebook è trovare all’interno di un dataset fornito i 10 volti che somigliano di più ai volti dei componenti del progetto. In particolare:

Come dataset si è utilizzato quello suggerito che contiene volti di personaggi famosi.

Import packages

Data Loader

Per poter effettuare correttamente il task di retrieval per prima cosa è necessario caricare tutte le immagini dei volti nei quali voglio trovare i più simili ad una data query.
Gli step di loading in questo caso saranno i seguenti:

  1. Caricamento ed estrazione in locale del file .zip
  2. Crop delle immagini in corrispondenza del volto
  3. Estrazione delle features per tutti i volti individuati, o un certo numero massimo definito.

Dopo lo step 3, dato l'alto tempo richiesto per la creazione di tutte le features, si è deciso di scrivere su file i dati estratti così da poterli ricaricare immediatamente negli step successivi.

Si procede quindi a scaricare e unzippare in locale il file .zip contenente tutte le immagini di volti famosi.

Funzioni utili

Una volta estratto in locale il file .zip è necessario procedere col punto $2$ e $3$, ovvero con l'individuazione del volto dell'immagini e la creazione delle features corrispondenti al crop del volto. Per evitare di salvare su disco anche tutte le immagini croppate, che richiederebbe molto spazio, le due operazioni vengono fatte in maniera consequenziale restituendo quindi le sole features.

Procedo dunque definendo delle funzioni di appoggio per il face detector e per la features extraction.

Face detector

Definisco la funzione per trovare il volto nelle immagini ed effettuare il crop. Si è deciso di utilizzare dlib come face detector.

Features extraction

Definisco le funzioni utili per estrarre le features data un immagine in input. Si è deciso di provare ad utilizzare due modelli neurali:

Ci attendiamo che il primo non restituisca buone features in quanto nel dataset originale di imagenet non sono presenti immagini di volti. Mentre con VGGFace ci aspettiamo risultati più accurati data una determinata query.

Definiamo dunque una funzione per estrarre le feature con MobileNetV2.

Definiamo una seconda funzione di appoggio per estrarre le features con VGGFace. Dopo alcuni tentativi si è deciso di utilizzare la prima versione di VGGFace basata sull'architettura VGG. Questo perchè i modelli più recenti di VGGFace come SENET50 e RESNET50 risultavano peggio nel task di retrieval.
La particolare implementazione scelta restituirà in output $512$ features per ogni immagine.

Definiamo anche una funzione di estrazione delle features dummy che non fa altro che ritornare i valori dell'immagine.

Save features

Definisco due funzioni di appoggio che permettono di salvare su file le features create e ricaricarle in un secondo momento. Così facendo è possibile risparmiare molto tempo e creare le features solo la prima volta.

Creazione dataset

Avendo definito le funzioni di appoggio è possibile combinarle correttamente per creare le features di riferimento per le immagini dei vip a nostra disposizione. Data la particolare struttura a sottocartelle è necessario implementare dei cicli per iterare sulle varie persone e sulle immagini a disposizione per ogni vip.

NOTA1: Qualora il face detector non individuasse alcun volto l'immagine verrà saltata, quindi non verranno create le corrispondenti features

NOTA2: In totale si hanno a disposizione oltre $200.000$ immagini di più di $1500$ vip. Creare le features di tutte queste immagini richiederebbe troppo tempo e troppe risorse computazionali, quindi verranno create le features solo di un subset di queste immagini.

MobileNet-V2

Le prime features che verranno create sfruttano la rete preaddestrata di MobileNet-V2. Una volta estratte le features verranno salvate su un file per evitare di doverle ricreare ad ogni avvio del notebook.

Possiamo notare come per ogni elemento si abbiamo a disposizione $1280$ features, come ci si attendeva da MobileNet-V2. Inoltre dal tempo riportato per la creazione notiamo che ci vuole circa un'ora per estrarre le features dei volti considerati.

VGGFace

Effettuaimo la medesima operazione precedente ma in questo caso verrà utilizzato VGGFace come modello neurale per l'estrazione delle features.

Possiamo notare come per ogni elemento si abbiamo a disposizione $512$ features, come ci si attendeva da VGGFace con architettura basata su avg ed average pooling. Infine, dato che VGGFace è un modello più complesso è possibile notare come la creazione delle features richieda più tempo rispetto a prima.

Retrieving similar image: mobilenet

Ricerco l'immagine più simile presente nel training set sfruttando la procedura di kdtree che è ottimizzata e permette di effettuare una ricerca efficiente. L'algoritmo funziona in questo modo:

  1. Divide lo spazio rispetto alla prima dimensione calcolando il mediano sull'asse orizzontale
  2. Divide lo spazio rispetto alla seconda dimensione calcolando il mediano sull'asse verticale
  3. Continua così per tutte le dimensioni e poi ricomincia dal primo punto.

Così si è creato un albero di ricerca che viene utilizzato per estrarre l'immagine più vicina in modo ottimizzato e senza verificare tutti i punti.

  1. Rispetto alla prima dimensione si chiede se la prima coordinata è maggiore o inferiore ed elimina i restanti punti
  2. Ripete il punto 1 per tutte le dimensioni.
  3. Si arriva ad un solo punto (foglia dell'albero) e quindi è un candidato ad essere uno dei più simili.
  4. Si percorre quindi a ritroso l'albero delle decisioni e si calcola la distanza della query rispetto al nodo corrente e si usano una serie di accorgimenti per non calcolarla rispetto a tutti i punti e tutte le dimensioni.

Come possiamo notare la creazione dell'albero richiede pochi secondi, trascurabili se si confrontano col tempo richiesto per la creazione delle features. Per questo motivo si è scelto di salvare l'array contenente le features invece dell'albero finale, inoltre questa scelta garantisce di poter cambiare successivamente la struttura per il retrieving senza dover estrarre nuovamente tutte le features ottimizzando così i tempi.

Definisco quindi una funzione che permetta, data un immagine di query, di estrarre le $k$ immagini più simili e visualizzarle a video.

Viene dunque effettuata per tutti e tre i componenti del gruppo la ricerca dei $10$ volti più simili.

Osservando i risultati ottenuti con MobileNet-V$2$ possiamo osservare che ci sono alcune similutidini tra l'immagine di query e la prima (in alcuni casi seconda) immagine individuata come più simile. Le successive immagini invece non sembrano essere particolarmente simili alla query.
Più specificatamente:

Come ci si aspettava MobileNet-V$2$ non sembra particolarmente adatto a questo task, inoltre spesso con query maschili vengono recuperate immagini femminili di volti simili e viceversa. Non ci si ritiene quindi molto soddisfatti del risultato! Per questo motivo si è provato ad implementare la medesima ricerca con VGGFace come estrattore di features.

Retrieving similar image: VGGFace

Ricerco l'immagine più simile presente nel training set sfruttando i medesimi passagi precedenti, tuttavia in questo caso uso le features estratte con VGGFace.

Come nel caso precedente l'albero richiede tempi di creazioni poco elevati, quindi si preferisce nuovamente mantenere il file con tutte le features invece che il solo albero. Procedo quindi visualizzando i 10 volti più simili per ciascun componente

Con questo estrattore di features i risultati migliorano molto. Anche le immagini successive alla prima infatti hanno buona somiglianza con la query in input. Inoltre spesso si possono notare somiglianze in più particolari contemporaneamente come occhiali, sopracciglia, naso, espressione, etc... Infine possiamo notare che soltanto in un caso le immagini recuperate riportano persone del sesso opposto, mentre per tutti gli altri casi nei primi dieci volti più simili viene mantenuto il sesso presente nel volto di query. Sicuramente questo estrattore, come ci si attendeva, da risultati migliori.

Considerazioni Finali

In conclusione è possibile osservare che il task risulta essere complesso e richiede un grande sforzo computazionale per creare le features ed estrarre i volti per tutto il dataset di riferimento. Tuttavia l'estrazione e la creazione delle features viene fatta un'unica volta all'inizio e poi rimane costante. Questo può permettere di realizzare estrattori più efficienti che elaborano piccoli batch di immagini per evitare problemi di OOM oppure con esecuzioni parallele su sottoporzioni dell'intero dataset.
Inoltre, come già anticipato, si è preferito salvare le features piuttosto che l'albero finale utilizzato per il retrieving perchè questo garantisce più flessibilita in quanto la creazione dell'albero richiede molto meno tempo e così facendo:

Per quanto riguarda i risultati ottenuti ci si può ritenere abbastanza soddisfatti, sicuramente una miglioria sarebbe quella di considerare tutti i volti a disposizione. Inoltre se si analizza il retrieving di VGGFace per Ginevra si può notare che ci sono più volti riferiti alla stessa persona, questo può essere un risultato non voluto e che quindi potrebbe essere oggetto di migliorie future.
Infine si è notato che la qualità dell'immagine in input, sia per la query che per i volti vip, inficia molto il risultato del retrieving.